package org.ruizhijie.run;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;

import java.net.InetSocketAddress;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.ruizhijie.topic.TopicQueue;
import org.ruizhijie.topic.i.IPublisher;

public class InPort implements Runnable{
	private Logger log = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
	
	private IPublisher pub;
	private int port;
	private Bootstrap bootstrap;
	private Channel ch;
	
	public InPort(IPublisher publish,int port){
		this.pub = publish;
		this.port = port;
		
		this.bootstrap = new Bootstrap();
		bootstrap.group(TopicQueue.group)
			.option(ChannelOption.SO_REUSEADDR, true)
			.option(ChannelOption.SO_BROADCAST, true)
			.channel(NioDatagramChannel.class);
		
		// 监听本地端口, 收到数据时, 调用pub.publish()更新数据
		initReadChannel();
		ch = bootstrap.localAddress(new InetSocketAddress(port)).bind().syncUninterruptibly().channel();
		
		log.info("in 初始化完成");
		
	}
	
	/**
	 * 初始化读取通道
	 */
	private void initReadChannel() {
		bootstrap.handler(new ChannelInitializer<Channel>() {
			@Override
			protected void initChannel(Channel ch) throws Exception {
				ChannelPipeline pipeline = ch.pipeline();
				pipeline.addLast(new SimpleChannelInboundHandler<DatagramPacket>() {
					@Override
					protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg)
							throws Exception {
						String mm = msg.content().toString(CharsetUtil.UTF_8);
						log.info("read 收到读卡器消息"+mm);
						
						pub.publish(port+"", mm.getBytes());
					}
				});
			}
		});
	}
	
	@Override
	public void run() {
		try {
			ch.closeFuture().sync();
			log.info("in 初始化完成");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}	}

}
